#pragma once

#include "AST.h"
#include "Uses.h"
#include "Modifies.h"
using namespace std;

class DesignExtractor {
private:
	AST programAST;

	/**
	 * Private method that gathers the variable indexes used by the AST subtree
	 * @param *root the pointer to the root of the current subtree of the AST 
	 * @param &indexes the list of used variable indexes to be returned
	 */
	void getUsedIndexes(Node *root, vector<int> &indexes);
	
	/**
	 * Private method that populates the UsesTable recursively
	 * @param *root the pointer to the root of the current subtree of the AST 
	 * @param &usesTable the reference to the table to be populated
	 */
	void buildUses(Node *root, Uses &usesTable);
	
	/**
	 * Private method that gathers the variable indexes modified by the AST subtree
	 * @param *root the pointer to the root of the current subtree of the AST 
	 * @param &indexes the list of modified variable indexes to be returned
	 */
	void getModifiedIndexes(Node *root, vector<int> &indexes);

	/**
	 * Private method that populates the ModifiesTable recursively
	 * @param *root the pointer to the root of the current subtree of the AST 
	 * @param &modifiesTable the reference to the table to be populated
	 */
	void buildModifies(Node *root, Modifies &modifiesTable);
public:
	/** Initialises a DesignExtractor that extracts design elements 
	 *  from the AST passed in as the constructor's argument
	 *  @param programAST the AST of the program to be processed
	 */
	DesignExtractor(AST programAST);

	/**
	 * Populates the UsesTable of the program
	 * @param &usesTable the reference to the table to be populated
	 */
	void createUsesTable(Uses &usesTable);
	
	/**
	 * Populates the ModifiesTable of the program
	 * @param &modifiesTable the reference to the table to be populated
	 */
	void createModifiesTable(Modifies &modifiesTable);
};